package com.ayz.gateway.center.domain.service.remoting;


import com.ayz.gateway.api.request.ApplicationConfig;
import com.ayz.gateway.api.request.RegistryGatewayServiceProto;
import com.ayz.gateway.api.response.GatewayCommonResult;
import com.ayz.gateway.api.server.RegistryGatewayServiceGrpc;
import com.ayz.gateway.center.domain.repository.IApiRepository;
import com.ayz.gateway.center.domain.repository.IGatewayServiceRepository;
import com.ayz.gateway.common.constants.ApiData;
import com.ayz.gateway.common.constants.GatewayServiceData;
import com.ayz.gateway.common.constants.MethodData;
import com.ayz.gateway.common.result.ResponseCode;
import com.google.protobuf.Any;
import io.grpc.stub.StreamObserver;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName RegistryGatewayServiceImpl
 * @Description TODO: 网关服务注册服务的实现类
 * @Author 快乐的星球
 * @Date 2023/5/25 21:46
 * @Version 1.0
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RegistryGatewayServiceImpl extends RegistryGatewayServiceGrpc.RegistryGatewayServiceImplBase {
    /**
     * 网关服务的存储中心
     */
    private IGatewayServiceRepository gatewayServiceRepository;
    /**
     * 网关API存储中心
     */
    private IApiRepository apiRepository;
    @Override
    public void registryGatewayService(RegistryGatewayServiceProto.RegistryGatewayServiceRequest request, StreamObserver<GatewayCommonResult.GatewayResult> responseObserver) {
        String gatewayId = request.getGatewayId();//网关服务唯一标识ID
        String gatewayName = request.getGatewayName();//网关服务的名称
        String address = request.getAddress();//网关服务的地址
        String gatewayGroup = request.getGatewayGroup();//网关业务组的名称
        //1: 网关服务注册逻辑
        GatewayServiceData gatewayServiceData=new GatewayServiceData(gatewayId,gatewayName,address,gatewayGroup);
        gatewayServiceRepository.registryGatewayService(gatewayServiceData);
        //2: 根据网关业务组给当前网关服务分配API
        List<ApiData> apiDataList = apiRepository.getApiDataListByGroup(gatewayGroup);
        List<ApplicationConfig.ApiData> apiDataMessageList = buildApiDataMessage(apiDataList);
        //3:封装响应返回
        RegistryGatewayServiceProto.RegistryGatewayServiceResponse response = RegistryGatewayServiceProto.RegistryGatewayServiceResponse.newBuilder()
                .addAllApiData(apiDataMessageList).build();

        GatewayCommonResult.GatewayResult gatewayResult = GatewayCommonResult.GatewayResult.newBuilder().setCode(ResponseCode.COMMON_SUCCESS)
                .setData(Any.pack(response)).build();

        responseObserver.onNext(gatewayResult);
        responseObserver.onCompleted();
    }

    private List<ApplicationConfig.ApiData> buildApiDataMessage(List<ApiData> apiDataList){
        if(apiDataList==null || apiDataList.isEmpty()){
            return new ArrayList<>();
        }
        List<ApplicationConfig.ApiData> result=new ArrayList<>();
        for (ApiData apiData : apiDataList) {
            ApplicationConfig.ApiData.Builder builder = ApplicationConfig.ApiData.newBuilder();
            builder.setApplicationName(apiData.getApplicationName());
            builder.setInterfaceName(apiData.getInterfaceName());
            builder.setRpcRegistryAddress(apiData.getRpcRegistryAddress());
            builder.setIsAsync(apiData.isAsync());
            builder.setTimeout(apiData.getTimeout());

            //构建MethodData
            List<MethodData> methodDataList = apiData.getMethodDataList();
            if(methodDataList!=null && !methodDataList.isEmpty()){
                for (MethodData methodData : methodDataList) {
                    ApplicationConfig.MethodData.Builder methodDataBuilder = ApplicationConfig.MethodData.newBuilder();
                    methodDataBuilder.setUri(methodData.getUri());
                    methodDataBuilder.setMethodName(methodData.getMethodName());
                    methodDataBuilder.setIsAuth(methodData.isAuth());
                    methodDataBuilder.setParameterTypeName(methodData.getParameterTypeName());

                    builder.addMethodDataList(methodDataBuilder.build());
                }
            }
            result.add(builder.build());
        }
        return result;
    }
}

